package com.lightsaber.trade.as.web.planfirst;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.interceptor.SessionAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.lightsaber.trade.as.entity.category.Category;
import com.lightsaber.trade.as.entity.planning.Level1Planning;
import com.lightsaber.trade.as.service.category.CategoryService;
import com.lightsaber.trade.as.service.param.ParamObject;
import com.lightsaber.trade.as.service.param.impl.ParamObjectImpl;
import com.lightsaber.trade.as.service.planfirst.PlanFirstLevelManager;
import com.lightsaber.trade.core.web.BaseAction;

/**
 * @author jianliu
 * 
 */
@Namespace("/planfirst")
public class PlanFirstAction extends BaseAction implements SessionAware {

    private final static Logger LOG = LoggerFactory.getLogger(PlanFirstAction.class);

    private static final long serialVersionUID = -1336633283762169923L;

    protected Map<String, Object> session;

    @Override
    public void setSession(final Map<String, Object> session) {
        this.session = session;
    }

    @Autowired
    private transient PlanFirstLevelManager planFirstLevelManager;

    @Value(value = "#{appProperties['level.1.plan.page.size']}")
    private String PAGE_SIZE;

    @Autowired
    private transient CategoryService categoryService;

    private Page<Level1Planning> page;
    private String level1PlanningId;

    private Level1Planning level1Planning;
    private String planningExerciseTemp;
    private boolean clear;
    private boolean search;

    private String planYearTem;
    private String planningExerciseTem;

    private String exerciseName;

    private Operator operator;

    @Override
    public String execute() {
        return list();
    }

    public String list() {
        setSearch(search);
        if (clear || !search) {// Click 'Clear' button
            planYearTem = null;
            planningExerciseTem = null;
            level1Planning = null;
            return SUCCESS;
        }

        if (page == null) {// Click 'Search' button first
            page = new Page<Level1Planning>(Integer.valueOf(PAGE_SIZE));
        } else {// Click 'Search' button
            page.setPageSize(Integer.valueOf(PAGE_SIZE));
        }

        if (!page.isOrderBySetted()) {
            page.setOrderBy("planningExercise");
            page.setOrder(Page.ASC);
        }

        // ---------- Generate query conditions ----------------START
        List<String> categoryIds = new ArrayList<String>();

        if (level1Planning != null && level1Planning.getCategory() != null
                && StringUtils.isNotBlank(level1Planning.getCategory().getId())) {
            categoryIds.add(level1Planning.getCategory().getId());

            planFirstLevelManager.findPage(page,
                    categoryIds.toArray(new String[categoryIds.size()]));

            return SUCCESS;
        }

        List<Category> categoryList = new ArrayList<Category>();

        String role = (String) session.get(ROLE_CODE);
        Integer planYear = null;

        if (operator == Operator.OWNER) {
            if (level1Planning == null || level1Planning.getPlanningExercise() == null) {
                List<ParamObject> trees = this.getPlanYearList();

                for (ParamObject paramObject : trees) {
                    planYear = Integer.valueOf(paramObject.getCode());
                    categoryList.addAll(categoryService
                            .findBranchTreesByYearAndRole(planYear, role));
                }

            } else if (level1Planning != null && level1Planning.getPlanningExercise() != null) {
                planYear = level1Planning.getPlanningExercise();
                categoryList.addAll(categoryService.findBranchTreesByYearAndRole(planYear, role));
            }

        } else {

            if (level1Planning == null || level1Planning.getPlanningExercise() == null) {
                List<ParamObject> trees = this.getPlanYearList();

                for (ParamObject paramObject : trees) {
                    planYear = Integer.valueOf(paramObject.getCode());
                    categoryList.addAll(categoryService.findBranchTreesByYearAndRoleForPlanner(
                            planYear, role));
                }

            } else if (level1Planning != null && level1Planning.getPlanningExercise() != null) {
                planYear = level1Planning.getPlanningExercise();
                categoryList.addAll(categoryService.findBranchTreesByYearAndRoleForPlanner(
                        planYear, role));
            }
        }

        for (Category category : categoryList) {
            categoryIds.add(category.getId());
        }
        // ---------- Generate query conditions ----------------END

        planFirstLevelManager.findPage(page, categoryIds.toArray(new String[categoryIds.size()]));

        return SUCCESS;
    }

    @Override
    public String input() throws Exception {
        if (StringUtils.isNotBlank(level1PlanningId)) {
            level1Planning = planFirstLevelManager.get(level1PlanningId);

            // Initial exerciseName.
            Category masterTree = categoryService.findMasterTreeByPlanYear(level1Planning
                    .getPlanningExercise());
            exerciseName = masterTree.getPlanningExerciseName();

        } else {

            // Get level1Planning.category.id from edit category page.
            String categoryId = level1Planning.getCategory().getId();
            Category category = categoryService.get(categoryId);

            // Get planning exercise name
            Integer planYear = category.getPlanYear();
            Category masterTree = categoryService.findMasterTreeByPlanYear(planYear);
            exerciseName = masterTree.getPlanningExerciseName();

            // Initial the planning
            level1Planning.getCategory().setBranchName(category.getBranchName());
            level1Planning.setPlanningExercise(planYear);
            operator = Operator.OWNER;
        }

        return INPUT;
    }

    public void validateSave() {
        boolean hasName = planFirstLevelManager.hasNameByCategory(level1Planning);
        if (hasName) {
            this.addActionError("In one owner node, name of first level planning must be unique.");
        }
    }

    public String save() throws Exception {
        planFirstLevelManager.save(level1Planning);
        level1PlanningId = level1Planning.getId();

        addActionMessage(getText(PROCESSED_SUCCESS));

        return input();
    }

    public String delete() throws Exception {
        planFirstLevelManager.delete(level1PlanningId);
        addActionMessage(getText(PROCESSED_SUCCESS));
        return list();
    }

    public String conifirmForEndorsement() throws Exception {

        planFirstLevelManager.conifirmForEndorsement(level1Planning);
        level1PlanningId = level1Planning.getId();
        addActionMessage(getText(PROCESSED_SUCCESS));

        return input();
    }

    /**
     * JQuery Ajax method
     */
    public void ajaxPlanningExerciseTemList() throws Exception {
        List<ParamObject> planningExerciseTemList = getPlanningExerciseTemList();

        Struts2Utils.renderJson(planningExerciseTemList);
    }

    /**
     * @return prepare DropdownList for PlanningExerciseTem
     * @throws Exception
     */
    public List<ParamObject> getPlanningExerciseTemList() throws Exception {

        Integer planYear = 0;
        if (level1Planning != null) {
            planYear = level1Planning.getPlanningExercise();
        }

        List<ParamObject> planningExerciseTemList = null;

        if (planYear != null && planYear > 0) {
            Category category = categoryService.findMasterTreeByPlanYear(planYear);
            planningExerciseTemList = new ArrayList<ParamObject>();

            planningExerciseTemList.add(new ParamObjectImpl(String.valueOf(category.getPlanYear()),
                    category.getPlanningExerciseName()));

        } else {
            planningExerciseTemList = categoryService.findMasterTrees();
            planningExerciseTemList.add(0, new ParamObjectImpl("", "- Select -"));
        }

        return planningExerciseTemList;
    }

    /**
     * ajax page
     * 
     * @return prepare Category drop down list for list page
     */
    public void ajaxCategoryList() {
        List<ParamObject> categoryList = getCategoryList();
        Struts2Utils.renderJson(categoryList);
    }

    /**
     * and initial page
     * 
     * @return prepare Category drop down list for list page
     */
    public List<ParamObject> getCategoryList() {
        List<ParamObject> categoryParamList = new ArrayList<ParamObject>();

        Integer planYear = 0;
        if (level1Planning != null) {
            planYear = level1Planning.getPlanningExercise();
        }

        if (planYear != null && planYear > 0) {
            String role = (String) session.get(ROLE_CODE);

            List<Category> categoryList = null;

            if (operator == Operator.OWNER) {
                categoryList = categoryService.findBranchTreesByYearAndRole(planYear, role);
            } else {
                categoryList = categoryService.findBranchTreesByYearAndRoleForPlanner(planYear,
                        role);
            }

            for (Category category : categoryList) {
                categoryParamList.add(new ParamObjectImpl(category.getId(), category
                        .getBranchName()));
            }
        }

        return categoryParamList;
    }

    /**
     * @return 准备PlanYear下拉框
     */
    public List<ParamObject> getPlanYearList() {
        LOG.debug("*******************");
        return categoryService.findMasterTrees();
    }

    public List<ParamObject> getSlashYearList() {
        return categoryService.getPlanYearWithSlashList();
    }

    public String getPlanningExerciseTemp() {
        return planningExerciseTemp;
    }

    public void setPlanningExerciseTemp(final String planningExerciseTemp) {
        this.planningExerciseTemp = planningExerciseTemp;
    }

    public String getLevel1PlanningId() {
        return level1PlanningId;
    }

    public void setLevel1PlanningId(final String level1PlanningId) {
        this.level1PlanningId = level1PlanningId;
    }

    public Page<Level1Planning> getPage() {
        return page;
    }

    public void setPage(final Page<Level1Planning> page) {
        this.page = page;
    }

    public String getPlanningExerciseTem() {
        return planningExerciseTem;
    }

    public Level1Planning getLevel1Planning() {
        return level1Planning;
    }

    public void setLevel1Planning(final Level1Planning level1Planning) {
        this.level1Planning = level1Planning;
    }

    public boolean isClear() {
        return clear;
    }

    public void setClear(final boolean clear) {
        this.clear = clear;
    }

    public void setPlanningExerciseTem(final String planningExerciseTem) {
        this.planningExerciseTem = planningExerciseTem;
    }

    public String getPlanYearTem() {
        return planYearTem;
    }

    public void setPlanYearTem(final String planYearTem) {
        this.planYearTem = planYearTem;
    }

    public boolean isSearch() {
        return search;
    }

    public void setSearch(final boolean search) {
        this.search = search;
    }

    public Operator getOperator() {
        return operator;
    }

    public void setOperator(final Operator operator) {
        this.operator = operator;
    }

    public String getExerciseName() {
        return exerciseName;
    }

    public void setExerciseName(final String exerciseName) {
        this.exerciseName = exerciseName;
    }

}
